/**
 * @ Author: 紫衣
 * @ Create Time: 2022-12-28 09:56:30
 * @ Modified by: --
 * @ Modified time: 2023-01-04 18:10:07
 * @ Description: canvas 配置工具，通过传入 ctx 和绘制图形的关键参数绘制形状
 * @ 持续集成中
 */

class Figure {
  constructor(cv, ctx, config) {
    this.cv = cv
    this.ctx = ctx

    this.config = Object.assign(
      {},
      {
        fillStyle: '#ccc',
        strokeStyle: '#eee',
      },
      config
    )
  }

  draw(type, args, isStroke) {
    this.ctx.beginPath()
    this.ctx.fillStyle = this.config.fillStyle
    this.ctx.strokeStyle = this.config.strokeStyle

    console.log('[ draw ] == ', type, '||', args)

    switch (type) {
      case 'rect':
        isStroke
          ? this.ctx.strokeRect(args.x, args.y, args.w, args.h)
          : this.ctx.fillRect(args.x, args.y, args.w, args.h)
        break
      case 'image':
        this.image(args)
        break
      case 'circle':
        this.ctx.arc(args.x, args.y, args.r, 0, 2 * Math.PI)
        isStroke ? this.ctx.stroke() : this.ctx.fill()
        break
      case 'star':
        this.star(args)
        isStroke ? this.ctx.stroke() : this.ctx.fill()
        break
      case 'love':
        this.love(args)
        isStroke ? this.ctx.stroke() : this.ctx.fill()
        break
      case 'polygon':
        this.polygon(args)
        isStroke ? this.ctx.stroke() : this.ctx.fill()
        break
      case 'code':
        this.code(args)
      default:
        break
    }

    this.ctx.closePath()
    this.ctx.save()
  }

  clear() {
    console.log('[ clear ] -- ')
    this.ctx.clearRect(0, 0, this.cv.width, this.cv.height)
  }

  /**
   * 图片
   * @param {*} ctx canvas.getContext2D
   * @param {x,y,w,h} args 参数：开始X、开始Y、宽度、高度
   * @param {image} 图片
   */
  image({ x, y, w, h, image }) {
    // 加个阴影好看一点
    this.ctx.shadowColor = 'gray'
    this.ctx.shadowOffsetX = 0
    this.ctx.shadowOffsetY = 0
    this.ctx.shadowBlur = 10

    let _image = new Image()
    _image.src = image
    // 这里不用加 onload，否则不连贯，
    // 其实图片在前面已经加载过了，直接用就好
    this.ctx.drawImage(_image, x, y, w, h)

    // 清除阴影，避免影响其他
    this.ctx.shadowBlur = 0
  }

  /**
   * 直线
   * @param {*} ctx canvas.getContext2D
   * @param {startX,startY,endX,endY} args 参数：开始X、开始Y、结束X、结束Y
   */
  line(ctx, args) {}

  /**
   * 文字
   * @param {*} param0
   */
  code({ x, y, size, code }) {
    this.ctx.font = `bold  ${size}px"微软雅黑"`

    this.ctx.fontWeight = 'bold'
    this.ctx.textAlign = 'center'
    this.ctx.textBaseline = 'middle'

    this.ctx.fillText(code, x, y)
  }

  /**
   * 星形
   * @param {*} ctx canvas.getContext2D
   * @param {cX,cY,radius,point} args 参数：圆心X、圆心Y、半径、星数
   */
  star({ x, y, r1, r2, n }) {
    console.log('star ::', x, y, r1, r2, n)
    for (let i = 0; i <= n * 2 + 1; i++) {
      let point =
        i % 2
          ? {
              x:
                Math.cos(((Math.PI * 2) / 360) * ((360 / (2 * n)) * i + 90)) *
                  r1 +
                x,
              y:
                Math.sin(((Math.PI * 2) / 360) * ((360 / (2 * n)) * i + 90)) *
                  r1 +
                y,
            }
          : {
              x:
                Math.cos(((Math.PI * 2) / 360) * ((360 / (2 * n)) * i + 90)) *
                  r2 +
                x,
              y:
                Math.sin(((Math.PI * 2) / 360) * ((360 / (2 * n)) * i + 90)) *
                  r2 +
                y,
            }
      if (i === 0) {
        this.ctx.moveTo(point.x, point.y)
      } else {
        this.ctx.lineTo(point.x, point.y)
      }
    }
  }

  /**
   * 多边形
   * @param {*} ctx canvas.getContext2D
   * @param {cx,cY,radius,side} args 参数：圆心X、圆心Y、半径、边数
   */
  polygon({ x, y, r, n }) {
    for (let i = 0; i <= n; i++) {
      let point = {
        x: Math.cos(((Math.PI * 2) / 360) * ((360 / n) * i)) * r + x,
        y: Math.sin(((Math.PI * 2) / 360) * ((360 / n) * i)) * r + y,
      }
      if (i === 0) {
        this.ctx.moveTo(point.x, point.y)
      } else {
        this.ctx.lineTo(point.x, point.y)
      }
    }
  }

  /**
   * 心形
   * x=12*sin(t)-4*sin(3*t)
   * y=13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t)
   */
  love({ x, y, r }) {
    let tmpR = r / 17

    function getX(t) {
      return tmpR * (12 * Math.sin(t) - 4 * Math.sin(3 * t))
    }
    function getY(t) {
      return (
        -tmpR *
        (13 * Math.cos(t) -
          5 * Math.cos(2 * t) -
          2 * Math.cos(3 * t) -
          Math.cos(4 * t))
      )
    }

    let radian_add = Math.PI / 180
    let radian = 0
    // this.ctx.translate(x, y)
    this.ctx.moveTo(getX(radian), getY(radian))
    while (radian <= Math.PI * 2) {
      //每增加一次弧度，绘制一条线
      radian += radian_add
      this.ctx.lineTo(
        getX(radian) + this.cv.width / 2,
        getY(radian) + this.cv.height / 2
      )
    }
  }
}

export default Figure
